#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##-- G55 -- S14 ------------------------------------------------------------##
__all__ = []

from .. import comparecards as cmp_cards
from .. import formlib as layout
from .. import pilelib as stack
from .. import quickplayscore as quickplay
from ..forms import (klondike as KlondikeLayout, freecell as FreeCellLayout,
                     canfield as CanfieldLayout,)
from ..gamelib import info as gi, state, game
from ..hint import CautiousDefaultHint
from ..packlib import info as cs
from ..piles import spider, scorpion
from ..utillib.misc import kwdefault

GT, SL = gi.GT, gi.SL
Wrap = stack.StackWrapper


class JollyRoger_Foundation(stack.SC_Foundation):
    """
    Build in rank by same color. _BOTTOM_IMAGE_ is rank.
    """
    _BOTTOM_IMAGE_ = 'rank'


class JollyRoger_RowStack(spider.SS_RK_RowStack):
    """
    Build in rank alone or pair ACE. Play seq in rank by same suit or ACE by
    same color. Drop full seq in rank by same suit on _foundation_ or full ACE
    pair by same color.
    """

    def _sequence(self, cards):
        """
        Overide for ACE played to match by color otherwise top card not ACE.
        Then check parent _sequence.

        :param sequence cards: cards from sending pile
        :return: right sequence?
        :rtype: boolean
        """
        if cards[1]['rank'] == cs.ACE:
            return cmp_cards.isSameColorSeqeunce(cards, dir=0)
        elif cards[-1]['rank'] == cs.ACE:  # 5-3-ACE
            return False
        return super(JollyRoger_RowStack, self)._sequence(cards)

    def _build_sequence(self, cards):
        """
        Overide for ACE played to match. Then check parent
        _build_sequence.

        :param sequence cards: cards from a sending pile
        :return: right sequence?
        :rtype: boolean
        """
        if cards[1]['rank'] == cs.ACE:
            return cmp_cards.isRankSeqeunce(cards, dir=0)
        return super(JollyRoger_RowStack, self)._build_sequence(cards)

    def canDropCards(self, stacks):
        """
        Overide for ACE drop by match of same color. Then check for sequence
        drop.

        :param sequence stacks: usually game.s.foundations
        :return: pile and number of cards.
        :rtype: Drop
        """
        cards = self.cards
        if not cards:
            return stack.Drop(None, 0)
        ncards = 0
        if self.TOPCARD['rank'] == cs.ACE:
            if (len(cards) >= 4 and
                cmp_cards.isSameColorSequence(cards[-4:], dir=0)):
                ncards = 4
        else:
            if (len(cards) >= 6 and
                cmp_cards.isSameSuitSequence(cards, **self.cap)):
                ncards = 6
        if ncards > 0:
            for s in stacks:
                if (s is not self and s.acceptsCards(self, cards[-ncards:])):
                    return (s, ncards)
        return stack.Drop(None, 0)


class RelaxedSpider(game.Game):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [6, 5, 5, 6, 5, 5, 6, 5, 5, 6]
      card. Build down in rank alone. Play seq by same suit. Full seq by same
      suit drop on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 8 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    """
    __info__ = dict(id=10, name='Relaxed Spider', game_type=(GT.SPIDER |
                    GT.RELAXED), decks=2, version='1.03',
                    skill_level=SL.MOSTLY_SKILL)
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _layout_ = layout.KlondikeLayout
    _talon_ = stack.DealRowTalon
    _waste_ = None
    _foundation_ = Wrap(spider.SS_Foundation, base_suit=cs.ANY)
    _row_ = spider.DropSS_RK_RowStack
    _hint_ = spider.Hint

    def _create_game(self, **kw):
        l, s = self._layout_(self), self.s
        kwdefault(kw, rows=10, texts=True, playcards=23)
        return super(RelaxedSpider, self)._create_game(**kw)

    def _start(self, rows=6, flip=False, **kw):
        """
        Deal initial cards for new game.
          - s[rows] LEN - 2 ea dn.
          - s[rows][0::3] 1 ea dn.
          - s[rows] 1 ea.

        .. \_start([rows=6, flip=False]) -> None
        """
        for i in range(rows - 2):
            self.s['talon'].dealRow(flip=flip, frames=0)
        self.s['talon'].dealRow(rows=self.s['rows'][0::3], flip=flip, frames=0)
        self.s['talon'].dealRow()

    _quickplay_ = quickplay.Spider


class Spider(RelaxedSpider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [6, 5, 5, 6, 5, 5, 6, 5, 5, 6]
      card. Build down in rank alone. Play seq by same suit. Drop full seq by
      same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ when no _row_ gap.

    _foundation_
      Pile 8 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.SpiderTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    """
    __info__ = dict(id=11, name='Spider', game_type=(GT.SPIDER | GT.POPULAR |
                    GT.GNOME | GT.XPAT), decks=2, skill_level=SL.MOSTLY_SKILL,
                    version='1.03')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = stack.SpiderTalon
    _waste_ = None


class Spider1Suit(Spider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [6, 5, 5, 6, 5, 5, 6, 5, 5, 6]
      card. Build down in rank alone. Play seq by same suit. Drop full seq by
      same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ when no _row_ gap.

    _foundation_
      Pile 8 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.SpiderTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    """
    __info__ = dict(id=269, name='Spider (1 Suit)', game_type=GT.SPIDER,
                    decks=2, skill_level=SL.MOSTLY_SKILL,
                    suits=(0,) * 4, version='0.80fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70


class Spider2Suits(Spider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [6, 5, 5, 6, 5, 5, 6, 5, 5, 6]
      card. Build down in rank alone. Play seq by same suit. Drop full seq by
      same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ when no _row_ gap.

    _foundation_
      Pile 8 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.SpiderTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    """
    __info__ = dict(id=270, name='Spider (2 Suits)', game_type=GT.SPIDER,
                    decks=2, skill_level=SL.MOSTLY_SKILL, suits=(0,
                    2,) * 2, version='0.80fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70


class OpenSpider(Spider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [6, 5, 5, 6, 5, 5, 6, 5, 5, 6]
      open card. Build down in rank alone. Play seq by same suit. Drop full
      seq by same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ when no _row_ gap.

    _foundation_
      Pile 8 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.SpiderTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    """
    __info__ = dict(id=461, name='Open Spider', game_type=GT.SPIDER, decks=2,
                    skill_level=SL.MOSTLY_SKILL,
                    altnames=('Beetle',), version='0.92fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows] LEN - 2 ea up.
          - s[rows][0::3] 1 ea up.
          - s[rows] 1 ea.

        .. \_start([rows=6, flip=True]) -> None
        """
        kw.setdefault('flip', True)
        super(OpenSpider, self)._start(**kw)


class BigSpider(Spider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 13 horz S _foundation_. Init deal 6 card. Build down in rank alone.
      Play seq by same suit. Drop full seq by same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ when no _row_ gap.

    _foundation_
      Pile 12 horz pile N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.SpiderTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    """
    __info__ = dict(id=384, name='Big Spider', game_type=GT.SPIDER, decks=3,
                    skill_level=SL.MOSTLY_SKILL, version='0.90fc',
                    altnames=('Spider (3 Decks)',))
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        kwdefault(kw, rows=13, playcards=28)
        return super(BigSpider, self)._create_game(kw)

    def _start(self, rows=6, flip=False, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 6 ea top.

        .. \_start([rows=6, flip=False]) -> None
        """
        for i in range(rows - 1):
            self.s.talon['dealRow'](frames=0, flip=flip)
        self.s.talon['dealRow']()


class BigSpider1Suit(BigSpider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 13 horz S _foundation_. Init deal 6 card. Build down in rank alone.
      Play seq by same suit. Drop full seq by same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ when no _row_ gap.

    _foundation_
      Pile 12 horz pile N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.SpiderTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    """
    __info__ = dict(id=445, name='Big Spider (1 Suit)', game_type=GT.SPIDER,
                    decks=3, skill_level=SL.MOSTLY_SKILL,
                    suits=(0,) * 4, version='0.92fc',
                    altnames=('Spider (3 Decks, 1 Suit)',))
    __author__ = 'Skomoroh'
    __version__ = 7.70


class BigSpider2Suits(BigSpider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 13 horz S _foundation_. Init deal 6 card. Build down in rank alone.
      Play seq by same suit. Drop full seq by same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ when no _row_ gap.

    _foundation_
      Pile 12 horz pile N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.SpiderTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    """
    __info__ = dict(id=446, name='Big Spider (2 Suits)', game_type=GT.SPIDER,
                    decks=3, skill_level=SL.MOSTLY_SKILL, suits=(0,
                    2,) * 2, version='0.92fc',
                    altnames=('Spider (3 Decks, 2 Suits)',))
    __author__ = 'Skomoroh'
    __version__ = 7.70


class Spider3x3(BigSpider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 13 horz S _foundation_. Init deal 6 card. Build down in rank alone.
      Play seq by same suit. Drop full seq by same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ when no _row_ gap.

    _foundation_
      Pile 9 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.SpiderTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    """
    __info__ = dict(id=449, name='Spider 3×3',
                    game_type=(GT.SPIDER | GT.ORIGINAL), decks=3,
                    skill_level=SL.MOSTLY_SKILL,
                    suits=tuple(range(3)), version='0.92fc',
                    altnames=('Spider (3 Decks, 3 Suits)',))
    __author__ = 'Skomoroh'
    __version__ = 7.70


class Spider4Decks(BigSpider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 13 horz S _foundation_. Init deal 6 card. Build down in rank alone.
      Play seq by same suit. Drop full seq by same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ when no _row_ gap.

    _foundation_
      Pile 16 horz pile N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.SpiderTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    """
    __info__ = dict(id=454, name='Spider (4 Decks)', game_type=GT.SPIDER,
                    decks=4, skill_level=SL.MOSTLY_SKILL,
                    version='0.92fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70


class ChineseSpider(BigSpider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 12 horz S _foundation_. Init deal 6 card. Build down in rank alone.
      Play seq by same suit. Drop full seq by same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ when no _row_ gap.

    _foundation_
      Pile 12 horz pile N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.SpiderTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    """
    __info__ = dict(id=670, name="Chinese Spider", game_type=GT.SPIDER,
                    decks=4, skill_level=SL.MOSTLY_SKILL,
                    suits=tuple(range(3)), version='0.94fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        kwdefault(kw, rows=12, playcards=28)
        return super(ChineseSpider, self)._create_game(**kw)


class BlackWidow(Spider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [6, 5, 5, 6, 5, 5, 6, 5, 5, 6]
      card. Build down in rank alone. Play seq. Drop full seq by same suit on
      _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ when no _row_ gap.

    _foundation_
      Pile 8 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.SpiderTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropRK_RowStack
    """
    __info__ = dict(id=49, name='Black Widow', game_type=GT.SPIDER, decks=2,
                    skill_level=SL.MOSTLY_SKILL, version='3.00',
                    altnames=('Scarab',))
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _row_ = spider.DropRK_RowStack


class Tarantula(Spider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [6, 5, 5, 6, 5, 5, 6, 5, 5, 6]
      card. Build down in rank alone. Play seq by same color. Drop full seq by
      same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ when no _row_ gap.

    _foundation_
      Pile 8 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.SpiderTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSC_RK_RowStack
    """
    __info__ = dict(id=680, name='Tarantula', game_type=GT.SPIDER, decks=2,
                    skill_level=SL.MOSTLY_SKILL, version='1.00fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = spider.DropSC_RK_RowStack

    _quickplay_ = quickplay.Tarantula


class GroundsForADivorce(RelaxedSpider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 10 horz S _foundation_. Init deal 5 open card. Build down in rank
      by same suit wrap. Play seq. Drop full seq on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ with cards.

    _foundation_
      Pile 8 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.HarpLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.GroundsForADivorceTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_rank=ANY, mod=13)
    :cvar Stack _row_: spider.DropSC_RK_RowStack (mod=13)
    """
    __info__ = dict(id=14, name='Grounds for a Divorce', game_type=(GT.SPIDER
                    | GT.POPULAR | GT.ATARI), decks=2, version='1.10',
                    skill_level=SL.MOSTLY_SKILL,
                    altnames=('Scheidungsgrund',))
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _layout_ = layout.HarpLayout
    _talon_ = stack.GroundsForADivorceTalon
    _foundation_ = Wrap(spider.SS_Foundation, base_rank=cs.ANY, mod=13)
    _row_ = Wrap(spider.DropSS_RK_RowStack, mod=13)

    def _create_game(self, **kw):
        kw.setdefault('playcards', 22)
        return super(GroundsForADivorce, self)._create_game(**kw)

    def _start(self, rows=5, flip=True, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 5 ea up.

        .. \_start([rows=5, flip=True]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(frames=0, flip=flip)
        self.s['talon'].dealRow()


class GroundsForADivorce3Decks(GroundsForADivorce):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 13 horz S _foundation_. Init deal 6 card. Build down in rank
      by same suit wrap. Play seq. Drop full seq on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ with cards.

    _foundation_
      Pile 12 horz pile N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.HarpLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.GroundsForADivorceTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_rank=ANY, mod=13)
    :cvar Stack _row_: spider.DropSC_RK_RowStack (mod=13)
    """
    __info__ = dict(id=401, name='Big Divorce', game_type=GT.SPIDER, decks=3,
                    skill_level=SL.MOSTLY_SKILL, version='0.90fc',
                    altnames=('Grounds for a Divorce (3 Decks)',))
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        kwdefault(kw, rows=13, playcards=28)
        return super(GroundsForADivorce3Decks, self)._create_game(**kw)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 6 ea top.

        .. \_start([rows=6, flip=False]) -> None
        """
        kwdefault(kw, rows=6, flip=False)
        super(GroundsForADivorce3Decks, self)._start(**kw)


class GroundsForADivorce4Decks(GroundsForADivorce3Decks):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 12 horz S _foundation_. Init deal 6 card. Build down in rank
      by same suit wrap. Play seq. Drop full seq on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ with cards.

    _foundation_
      Pile 16 horz pile N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.HarpLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.GroundsForADivorceTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_rank=ANY, mod=13)
    :cvar Stack _row_: spider.DropSC_RK_RowStack (mod=13)
    """
    __info__ = dict(id=455, name='Very Big Divorce', game_type=GT.SPIDER,
                    decks=4, skill_level=SL.MOSTLY_SKILL,
                    version='0.92fc',
                    altnames=('Grounds for a Divorce (4 Decks)',))
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        kwdefault(kw, rows=12, playcards=32)
        return super(GroundsForADivorce4Decks, self)._create_game(kw)


class York(GroundsForADivorce):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 12 horz S _foundation_. Init deal [8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 8,
      8] card. Build down in rank alone. Play seq by same suit. Drop full seq
      by same suit on _foundation_.

    _foundation_
      Pile 8 piles horz. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_rank=ANY, mod=13)
    :cvar Stack _row_: spider.DropSC_RK_RowStack (mod=13)
    """
    __info__ = dict(id=441, name='York', game_type=(GT.SPIDER | GT.OPEN |
                    GT.ORIGINAL), decks=2, skill_level=SL.SKILL,
                    version='0.92fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = stack.InitialDealTalon
    _layout_ = layout.KlondikeLayout

    def _create_game(self, **kw):
        kwdefault(kw, rows=12, playcards=26, texts=False)
        return super(York, self)._create_game(**kw)

    def _start(self, rows=9, flip=True, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 8 ea up.
          - s[rows][2:-2] 1 ea.

        .. \_start([rows=9, flip=True]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(frames=0, flip=flip)
        self.s['talon'].dealRow(rows=self.s['rows'][2:-2])


class BigYork(York):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 14 horz S _foundation_. Init deal [12, 11, 11, 11, 11, 11, 11, 11,
      11, 11, 11, 11, 12] card. Build down in rank alone. Play seq by same
      suit. Drop full seq by same suit on _foundation_.

    _foundation_
      12 piles N _row_. Drop from _row_. Play none.
    ------
    versionadded:: 5.92
    versionchanged:: *NEXT_VERSION*
      Refactored class. Add comments.
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_rank=ANY, mod=13)
    :cvar Stack _row_: spider.DropSC_RK_RowStack (mod=13)
    """
    __info__ = dict(id=444, name='Big York', game_type=GT.SPIDER | GT.OPEN |
                    GT.ORIGINAL, decks=3, skill_level=SL.SKILL,
                    version='0.92fc', altnames=('York (3 Decks)',))
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        kw.setdefault('rows', 14)
        return super(BigYork, self)._create_game(**kw)

    def _start(self, rows=12, flip=True, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 11 ea up.
          - s[rows][0::13] 1 ea.

        .. \_start([rows=12, flip=True]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(frames=0, flip=flip)
        self.s['talon'].dealRow(rows=self.s['rows'][0::13])


class GrandmothersGame(RelaxedSpider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 10 horz S _foundation_. Init deal 6 open card. Build down in rank
      alone. Play seq by same suit. Drop full seq by same suit on
      _foundation_.

    _talon_
      Pile 1 SE. Deal 1 card on _row_.

    _foundation_
      8 piles S. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.HarpLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    """
    __info__ = dict(id=114, name='Grandmotherʼs Game', game_type=GT.SPIDER,
                    decks=2, skill_level=SL.MOSTLY_SKILL,
                    version='3.10')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _layout_ = layout.HarpLayout

    def _create_game(self, **kw):
        kw.setdefault('playcards', 22)
        return super(GrandmothersGame, self)._create_game(**kw)

    def _start(self, rows=6, flip=True, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 6 ea up.

        .. \_start([rows=6, flip=True]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(frames=0, flip=flip)
        self.s['talon'].dealRow()


class MrsMop(RelaxedSpider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 13 horz S _foundation_. Init deal 8 open card. Build down in rank
      alone. Play seq by same suit. Drop full seq by same suit on
      _foundation_.

    _foundation_
      8 piles N. Drop from _row_. Play none.

    seealso::
      <http://en.wikipedia.org/wiki/Mrs._Mop>
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    """
    __info__ = dict(id=309, name='Mrs. Mop', game_type=(GT.SPIDER | GT.OPEN),
                    decks=2, skill_level=SL.SKILL,
                    version='0.80fc')
    __author__ = 'Skomoroh'
    __credits__ = ['Charles Jewell']
    __version__ = 7.70

    _talon_ = stack.InitialDealTalon

    def _create_game(self, **kw):
        kwdefault(kw, rows=13, playcards=24, texts=False)
        return super(MrsMop, self)._create_game(**kw)

    def _start(self, rows=8, flip=True, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 8 ea up.

        .. \_start([rows=8, flip=True]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(frames=0, flip=flip)
        self.s['talon'].dealRow()


class Rachel(RelaxedSpider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 6 horz S _foundation_. Init deal 1 card. Build down in rank
      alone. Play seq. Drop full seq by same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal _waste_ a card.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropRK_RowStack
    """
    __info__ = dict(id=194, name='Rachel', game_type=(GT.SPIDER |
                    GT.XORIGINAL), decks=1,
                    skill_level=SL.MOSTLY_SKILL, version='4.41')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = stack.WasteTalon
    _waste_ = stack.WasteStack
    _row_ = spider.DropRK_RowStack

    def _create_game(self, **kw):
        kw.setdefault('rows', 6)
        return super(Rachel, self)._create_game(**kw)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 1 ea.

        .. \_start([]) -> None
        """
        self.s['talon'].dealRow()


class SpiderWeb(RelaxedSpider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 7 horz S _foundation_. Init deal [4, 4, 4, 3, 3, 3, 3] open card.
      Build down in rank alone. Play seq by same suit. Drop full seq by same
      suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _waste_
      Pile 1 E _talon_. Hold a card. Play top.

    _foundation_
      Pile 4 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: stack.ReserveStack
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    """
    __info__ = dict(id=359, name='Spider Web', game_type=GT.SPIDER, decks=1,
                    skill_level=SL.BALANCED, version='0.90fc')
    __author__ = 'Skomoroh'
    __credits__ = ['Thomas Warfield']
    __version__ = 7.70

    _waste_ = stack.ReserveStack

    def _create_game(self, **kw):
        kwdefault(kw, rows=7, playcards=16)
        return super(SpiderWeb, self)._create_game(**kw)

    def _start(self, rows=4, flip=True, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 4 ea up.
          - s[rows][:3] 1 ea.

        .. \_start([rows=4, flip=True]) -> None
        """
        for i in range(rows - 2):
            self.s['talon'].dealRow(frames=0, flip=flip)
        self.s['talon'].dealRow(rows=self.s['rows'] + self.s['rows'][:3])


class Spiderette(Spider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 7 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7] card. Build
      down in rank alone. Play seq by same suit. Drop full seq by same suit on
      _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ while no gap.

    _foundation_
      Pile 4 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.SpiderTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    """
    __info__ = dict(id=24, name='Spiderette', game_type=(GT.SPIDER |
                    GT.GNOME), decks=1, skill_level=SL.BALANCED,
                    version='2.90')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    def _create_game(self, **kw):
        kwdefault(kw, rows=7, playcards=20)
        return super(Spiderette, self)._create_game(**kw)

    def _start(self, flip=False, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 1..LEN ea top.

        .. \_start([flip=False]) -> None
        """
        for i in range(1, len(self.s['rows'])):
            self.s.talon.dealRow(rows=self.s['rows'][i:], flip=False, frames=0)
        self.s['talon'].dealRow()


class BabySpiderette(Spiderette):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 7 S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7] card. Build
      down in rank alone. Play seq. Drop full seq by same suit on
      _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ while no gap.

    _foundation_
      Pile 4 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.SpiderTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropRK_RowStack
    """
    __info__ = dict(id=47, name='Baby Spiderette', game_type=GT.SPIDER,
                    decks=1, skill_level=SL.BALANCED,
                    version='3.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _row_ = spider.DropRK_RowStack


class WillOTheWisp(Spiderette):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 7 horz S _foundation_. Init deal 3 card. Build down in rank alone.
      Play seq by same suit. Drop full seq by same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ while no gap.

    _foundation_
      Pile 4 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.SpiderTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    """
    __info__ = dict(id=48, name='Will oʼ the Wisp', game_type=(GT.SPIDER |
                    GT.GNOME), decks=1, skill_level=SL.BALANCED,
                    version='2.90')
    __author__ = 'Markus Oberhumer'
    __credits__ = ['Albert Morehead', 'Geoffrey Mott-Smith']
    __version__ = 7.70

    def _start(self, rows=3, flip=False, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 3 ea top.

        .. \_start([rows=3, flip=False]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(frames=0, flip=flip)
        self.s['talon'].dealRow()


class SimpleSimon(Spider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [8, 8, 8, 7, 6, 5, 4, 3, 2, 1]
      card. Build down in rank alone. Play top as seq by same suit. Drop full
      seq by same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ while no gap.

    _foundation_
      Pile 4 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.SuperMoveDropSS_RK_RowStack
    """
    __info__ = dict(id=50, name='Simple Simon', game_type=(GT.SPIDER | GT.OPEN
                    | GT.KDE), decks=1, skill_level=SL.MOSTLY_SKILL,
                    version='2.90')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = stack.InitialDealTalon
    _row_ = spider.SuperMoveDropSS_RK_RowStack

    def _create_game(self, **kw):
        kwdefault(kw, rows=10, texts=False)
        return super(SimpleSimon, self)._create_game(**kw)

    def _start(self, flip=True, **kw):
        """
        Deal initial cards for new game.
          - s[rows] LEN - 2, LEN - 2, LEN - 2..1 ea up.

        .. \_start([flip=True]) -> None
        """
        for i in range(1, len(self.s['rows']) - 2):
            self.s['talon'].dealRow(rows=self.s['rows'][:-i], frames=0,
                                    flip=flip)
        self.s['talon'].dealRow()


class SimpleSimonII(SimpleSimon):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [8, 8, 8, 7, 6, 5, 4, 3, 2, 1]
      card. Build down in rank alone wrap. Play top as seq by same suit. Drop
      full seq  by same suit wrap on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ while no gap.

    _foundation_
      Pile 4 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_rank=ANY, mod=13)
    :cvar Stack _row_: spider.SuperMoveDropSS_RK_RowStack (mod=13)
    """
    __info__ = dict(id=951, name='Simple Simon Ⅱ', game_type=(GT.SPIDER |
                    GT.OPEN | GT.HIDDEN), decks=1,
                    skill_level=SL.MOSTLY_SKILL, version='0.70up')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _foundation_ = Wrap(spider.SS_Foundation, base_rank=cs.ANY, mod=13)
    _row_ = Wrap(spider.SuperMoveDropSS_RK_RowStack, mod=13)


class SimonJester(Spider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 14 horz S _foundation_. Init deal [13, 13, 12, 11, 10, 9, 8, 7, 6,
      5, 4, 3, 2, 1] card. Build down in rank alone. Play top as seq by same
      suit. Drop full seq by same suit on _foundation_.

    _foundation_
      8 piles N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    """
    __info__ = dict(id=366, name='Simon Jester', game_type=(GT.SPIDER |
                    GT.OPEN), decks=2, skill_level=SL.MOSTLY_SKILL,
                    version='0.90fc')
    __author__ = 'Skomoroh'
    __credits__ = ['Adam Selene']
    __version__ = 7.70

    _talon_ = stack.InitialDealTalon

    def _create_game(self, **kw):
        kwdefault(kw, rows=14, texts=False)
        return super(SimonJester, self)._create_game(**kw)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows] LEN - 1, LEN - 1..1 ea up.

        .. \_start([]) -> None
        """
        for i in range(1, len(self.s['rows'])):
            self.s['talon'].dealRow(rows=self.s['rows'][:i], frames=0)
        self.s['talon'].dealRow(rows=self.s['rows'][1:])


class Scorpion(RelaxedSpider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 7 horz S _foundation_. Init deal 7 top [4, 4, 4, 4, 7, 7, 7] open
      card. Build down in rank by same suit. Play any. Drop full seq by
      same suit on _foundation_. Base KING.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 4 horz N. Drop from _row_. Play none.

    note::
      ⟪highlight_play⟫ disabled
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: scorpion.Hint
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: scorpion.DropSS_RowStack (base_rank=KING)
    """
    __info__ = dict(id=29, name='Scorpion', game_type=(GT.SPIDER | GT.GNOME),
                    decks=1, skill_level=SL.MOSTLY_SKILL, version='2.90')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _hint_ = scorpion.Hint
    _row_ = Wrap(scorpion.DropSS_RowStack, base_rank=cs.KING)

    def _create_game(self, **kw):
        kwdefault(kw, rows=7, playcards=20)
        return super(Scorpion, self)._create_game(**kw)

    def _start(self, rows=7, deal=[4] * 3, **kw):
        """
        Deal initial cards for new game.
          - s[rows][:4] 3 ea dn.
          - s[rows][4:] 3 ea up.
          - s[rows] 4 ea up.

        .. \_start([rows=7, deal=[4] * 3]) -> None
        """
        for i in deal:
            self.s['talon'].dealRow(rows=self.s['rows'][:i], flip=False,
                                    frames=0)
            self.s['talon'].dealRow(rows=self.s['rows'][i:], flip=True,
                                    frames=0)
        for i in range(rows - len(deal) - 2):
            self.s['talon'].dealRow(rows=self.s['rows'], flip=True, frames=0)
        self.s['talon'].dealRow()
        self.s['talon'].dealRowAvail()

    @property
    def _highlight_piles(self):
        """
        Get stacks to highlight for possible move.

        :return: empty.
        :rtype: tuple
        """
        return ()


class DoubleScorpion(Scorpion):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [11, 11, 11, 11, 10, 10, 10, 10,
      10 ,10] top [6, 6, 6, 6, 6, 10, 10, 10, 10, 10] open card. Build down in
      rank by same suit. Play any. Drop full seq by same suit on _foundation_.
      Base KING.

    _foundation_
      8 piles N. Drop from _row_. Play none.

    note::
      ⟪highlight_play⟫ disabled
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: scorpion.Hint
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: scorpion.DropSS_RowStack (base_rank=KING)
    """
    __info__ = dict(id=511, name='Double Scorpion', game_type=GT.SPIDER,
                    decks=2, skill_level=SL.MOSTLY_SKILL,
                    version='0.93fc', altnames=('Scorpion (2 Decks)',))
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = stack.InitialDealTalon

    def _create_game(self, **kw):
        kwdefault(kw, rows=10, playcards=26, texts=False)
        return super(DoubleScorpion, self)._create_game(**kw)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows][:5] 5 ea dn.
          - s[rows][5:] 5 ea up.
          - s[rows] ~6 ea up.

        .. \_start([rows=11, deal=[5] * 5]) -> None
        """
        kw.setdefault('deal', rows=10, deal=[5] * 5)
        super(DoubleScorpion, self)._start(**kw)


class TripleScorpion(DoubleScorpion):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 12 horz S _foundation_. Init deal 12 top [7, 7, 7, 7, 7, 12, 12,
      12, 12, 12] open card. Build down in rank by same suit. Play any. Drop
      full seq by same suit on _foundation_. Base KING.

    _foundation_
      8 piles N. Drop from _row_. Play none.

    note:: ⟪highlight_play⟫ disabled
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: scorpion.Hint
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: scorpion.DropSS_RowStack (base_rank=KING)
    """
    __info__ = dict(id=512, name='Triple Scorpion', game_type=GT.SPIDER,
                    decks=3, skill_level=SL.MOSTLY_SKILL,
                    version='0.93fc', altnames=('Scorpion (3 Decks)',))
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = stack.InitialDealTalon

    def _create_game(self, **kw):
        kwdefault(kw, rows=13, playcards=30)
        return super(TripleScorpion, self)._create_game(**kw)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows][:5] 5 ea dn.
          - s[rows][5:] 5 ea up.
          - s[rows] ~7 ea up.

        .. \_start([rows=12, deal=[5] * 5]) -> None
        """
        kw.setdefault('rows', 12)
        super(TripleScorpion, self)._start(**kw)


class ScorpionII(Scorpion):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 7 horz S _foundation_. Init deal 7 top [3, 3, 3, 7, 7, 7, 7] open
      card. Build down in rank by same suit. Play any. Drop full seq by
      same suit on _foundation_. Base KING.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 4 horz N. Drop from _row_. Play none.

    note:: ⟪highlight_play⟫ disabled
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: scorpion.Hint
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: scorpion.DropSS_RowStack (base_rank=KING)
    """
    __info__ = dict(id=672, name='Scorpion Ⅱ', game_type=GT.SPIDER, decks=1,
                    skill_level=SL.MOSTLY_SKILL, version='1.00fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows][:3] 3 ea dn.
          - s[rows][3:] 3 ea up.
          - s[rows] 4 ea up.

        .. \_start([rows=7, deal=[5] * 5]) -> None
        """
        kw.setdefault('deal', [3] * 3)
        super(ScorpionII, self)._start(**kw)


class ScorpionTail(Scorpion):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 7 horz S _foundation_. Init deal 7 top [4, 4, 4, 4, 7, 7, 7] open
      card. Build down in rank by alt color. Play any. Drop full seq by alt
      color on _foundation_. Base KING.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 4 horz N. Drop from _row_. Play none.

    note:: ⟪highlight_play⟫ disabled
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: scorpion.Hint
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.AC_Foundation (base_suit=ANY)
    :cvar Stack _row_: scorpion.DropAC_RowStack (base_rank=KING)
    """
    __info__ = dict(id=346, name='Scorpion Tail', game_type=GT.SPIDER,
                    decks=1, skill_level=SL.MOSTLY_SKILL,
                    version='0.90fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _foundation_ = Wrap(spider.AC_Foundation, base_suit=cs.ANY)
    _row_ = Wrap(scorpion.DropAC_RowStack, base_rank=cs.KING)


class ScorpionHead(Scorpion):
    """
    Drop seq on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.freecell.FreecellLayout
        - row [7 horz S reserve and foundation, vert offset]
        - talon [1 SE, no offset]
        - foundation [4 horz NE, no offset]
        - reserve [4 horz NW, no offset]

    _row_
      Init deal [7, 7, 7, 8, 8, 8, 8] top [7, 7,
      7, 4, 4, 4, 4] open card. Build down in rank by same suit. Play any.
      Drop full seq by same suit on _foundation_. Base KING.

    _reserve_
      Hold a card. Play top.

    _talon_
      Deal 1 card on _row_.

    _foundation_
      Drop from _row_. Play none.

    note:: ⟪highlight_play⟫ disabled
    ------
    :cvar Hint _hint_: scorpion.Hint
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: scorpion.DropSS_RowStack (base_rank=KING)
    """
    __info__ = dict(id=345, name='Scorpion Head', game_type=(GT.SPIDER |
                    GT.GNOME), decks=1, skill_level=SL.MOSTLY_SKILL,
                    version='0.90fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = FreeCellLayout.FreeCellLayout

    def _create_game(self, **kw):
        kw.setdefault('reserves', 4)
        l, s = super(ScorpionHead, self)._create_game(**kw), self.s
        for r in l.s['reserves']:
            s['reserves'].append(self._reserve_(r.x, r.y, game=self))
        l.defaultAll()
        return l

    def _start(self, deal=[3] * 4 + [7] * 2, **kw):
        """
        Deal initial cards for new game.
          - s[rows][:4] 4 ea up.
          - s[rows][4:] 4 ea dn.
          - s[rows][:7] 2 ea up.
          - s[rows][7:] 2 ea dn.
          - s[rows] 1 ea.

        .. \_start([deal=[3] * 4 + [7] * 2]) -> None
        """
        for i in deal:
            self.s['talon'].dealRow(rows=self.s['rows'][:i], flip=True,
                                    frames=0)
            self.s['talon'].dealRow(rows=self.s['rows'][i:], flip=False,
                                    frames=0)
        self.s['talon'].dealRow(rows=self.s['rows'] + self.s['rows'][:3])

class Wasp(ScorpionII):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 7 horz S _foundation_. Init deal 6 top [3, 3, 3, 7, 7, 7, 7] open
      card. Build down in rank by same suit. Play any. Drop full seq by
      same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 4 horz N. Drop from _row_. Play none.

    note:: ⟪highlight_play⟫ disabled
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: scorpion.Hint
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: scorpion.DropSS_RowStack
    """
    __info__ = dict(id=185, name='Wasp', game_type=GT.SPIDER, decks=1,
                    skill_level=SL.MOSTLY_SKILL, version='4.41')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _row_ = scorpion.DropSS_RowStack


class ThreeBlindMice(ScorpionHead):
    """
    Drop seq on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.freecell.FreecellLayout
        - row [10 horz S reserve and foundation, vert offset]
        - talon [1 SE, no offset]
        - foundation [4 horz NE, no offset]
        - reserve [2 horz NW, no offset]

    _row_
      Init deal 5 top [5, 5, 5, 5, 5, 5, 5, 2, 2,
      2] open card. Build down in rank by same suit. Play any. Drop full seq
      by same suit on _foundation_. Base KING.

    _reserve_
      Init 1 card. Build none. Play top.

    _talon_
      Deal 1 card on _row_.

    _foundation_
      Drop from _row_. Play none.

    note:: ⟪highlight_play⟫ disabled
    ------
    :cvar Layout _layout_: layout.FreeCellLayout
    :cvar Hint _hint_: scorpion.Hint
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: scorpion.DropSS_RowStack (base_rank=KING)
    :cvar Stack _reserve_: stack.OpenStack
    """
    __info__ = dict(id=305, name='Three Blind Mice', game_type=GT.SPIDER,
                    decks=1, skill_level=SL.MOSTLY_SKILL,
                    version='0.80fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = stack.InitialDealTalon
    _reserve_ = stack.OpenStack

    def _create_game(self, **kw):
        kwdefault(kw, rows=10, reserves=2, playcards=15)
        return super(ThreeBlindMice, self)._create_game(**kw)

    def _start(self, rows=5, **kw):
        """
        Deal initial cards for new game.
          - s[rows][:7] ROWS - 2 ea up.
          - s[rows][7:] ROWS - 2 ea dn.
          - s[rows] 2 ea up.
          - s[reserves] 1 ea.

        .. \_start([rows=5]) -> None
        """
        for i in deal:
            self.s['talon'].dealRow(rows=self.s['rows'][:7], flip=True,
                                    frames=0)
            self.s['talon'].dealRow(rows=self.s['rows'][7:], flip=False,
                                    frames=0)
        self.s['talon'].dealRow(frames=0)
        self.s['talon'].dealRow()
        self.s['talon'].dealRow(rows=self.s['reserves'])


class FarmersWife(ThreeBlindMice):
    """
    Drop seq on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.freecell.FreecellLayout
        - row [10 horz S reserve and foundation, vert offset]
        - talon [1 SE, no offset]
        - foundation [4 horz NE, no offset]
        - reserve [2 horz NW, no offset]

    _row_
      Init deal 5 top [5, 5, 5, 5, 5, 5, 5, 2, 2,
      2] open card. Build down in rank by alt color. Play any. Drop full seq
      by alt color on _foundation_. Base KING.

    _reserve_
      Init 1 card. Build none. Play top.

    _talon_
      Deal 1 card on _row_.

    _foundation_
      Drop from _row_. Play none.

    note:: ⟪highlight_play⟫ disabled
    ------
    :cvar Layout _layout_: layout.FreeCellLayout
    :cvar Hint _hint_: scorpion.Hint
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.AC_Foundation (base_suit=ANY)
    :cvar Stack _row_: scorpion.DropAC_RowStack (base_rank=KING)
    :cvar Stack _reserve_: stack.OpenStack
    """
    __info__ = dict(id=543, name='Farmerʼs Wife', game_type=GT.SPIDER,
                    decks=1, skill_level=SL.MOSTLY_SKILL,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _foundation_ = Wrap(spider.AC_Foundation, base_suit=cs.ANY)
    _row_ = Wrap(scorpion.DropAC_RowStack, base_rank=cs.KING)


class HowTheyRun(ThreeBlindMice):
    """
    Drop seq on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.freecell.FreecellLayout
        - row [10 horz S reserve and foundation, vert offset]
        - talon [1 SE, no offset]
        - foundation [4 horz NE, no offset]
        - reserve [2 horz NW, no offset]

    _row_
      Init deal 5 top [5, 5, 5, 5, 5, 5, 5, 2, 2,
      2] open card. Build down in rank by same suit. Play any. Drop full seq
      by same suit on _foundation_. Base KING.

    _reserve_
      Init 1 card. Build 1 card. Play top.

    _talon_
      Deal 1 card on _row_.

    _foundation_
      Drop from _row_. Play none.

    note:: ⟪highlight_play⟫ disabled
    ------
    :cvar Layout _layout_: layout.FreeCellLayout
    :cvar Hint _hint_: scorpion.Hint
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation (base_suit=ANY)
    :cvar Stack _row_: scorpion.DropSS_RowStack (base_rank=KING)
    :cvar Stack _reserve_: stack.ReserveStack
    """
    __info__ = dict(id=544, name='How They Run', game_type=GT.SPIDER,
                    decks=1, skill_level=SL.MOSTLY_SKILL,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _reserve_ = stack.ReserveStack


class Spidike(RelaxedSpider):
    """
    Finish seq on _foundation_ within a turn.

    _row_
      Pile 7 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7] open card.
      Build down in rank alone. Play seq by same suit. Full seq drop by same
      suit on _foundation_. Base KING.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: spider.DropSS_RK_RowStack (base_rank=KING)
    """
    __info__ = dict(id=458, name='Spidike', game_type=GT.SPIDER, decks=1,
                    skill_level=SL.BALANCED, version='0.92fc')
    __author__ = 'Skomoroh'
    __credits__ = ['Thomas Warfield']
    __version__ = 7.70

    _foundation_ = stack.SS_Foundation
    _row_ = Wrap(spider.SS_RK_RowStack, base_rank=cs.KING)

    def _create_game(self, **kw):
        kwdefault(kw, rows=7, playcards=18)
        return super(Spidike, self)._create_game(**kw)

    def _start(self, flip=True, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 1..LEN ea up.

        .. \_start([flip=True]) -> None
        """
        for i in range(1, len(self.s['rows'])):
            self.s['talon'].dealRow(rows=self.s['rows'][i:], flip=flip,
                                    frames=0)
        self.s['talon'].dealRow()


class FredsSpider(Spidike):
    """
    Finish seq on _foundation_ within a turn.

    _row_
      Pile 10 horz S _foundation_. Init deal 5 card. Build down in rank alone.
      Play seq by same suit. Full seq drop by same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: spider.SS_RK_RowStack
    """
    __info__ = dict(id=459, name='Fredʼs Spider', game_type=GT.SPIDER,
                    decks=2, skill_level=SL.MOSTLY_SKILL,
                    version='0.92fc')
    __author__ = 'Skomoroh'
    __credits__ = ['Fred Lunde']
    __version__ = 7.70

    _row_ = spider.SS_RK_RowStack

    def _create_game(self, **kw):
        kwdefault(kw, rows=10, playcards=23)
        return super(FredsSpider, self)._create_game(**kw)

    def _start(self, rows=5, flip=False, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 5 ea top.

        .. \_start([rows=5, flip=False,]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(frames=0, flip=flip)
        self.s['talon'].dealRow()


class FredsSpider3Decks(FredsSpider):
    """
    Finish seq on _foundation_ within a turn.

    _row_
      Pile 13 horz S _foundation_. Init deal 5 card. Build down in rank alone.
      Play seq by same suit. Full seq drop by same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 12 horz pile N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: spider.SS_RK_RowStack
    """
    __info__ = dict(id=460, name='Fredʼs Spider (3 Decks)',
                    game_type=GT.SPIDER, decks=3,
                    skill_level=SL.MOSTLY_SKILL, version='0.92fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        kwdefault(kw, rows=13, playcards=26)
        return super(FredsSpider3Decks, self)._create_game(**kw)


class Incompatibility(FredsSpider):
    """
    Finish seq on _foundation_ within a turn.

    _row_
      Pile 10 horz S _foundation_. Init deal 5 card. Build down in rank alone.
      Play seq by same suit. Full seq drop by same suit on _foundation_.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ with cards.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.GroundsForADivorceTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: spider.SS_RK_RowStack
    """
    __info__ = dict(id=671, name='Incompatibility', game_type=GT.SPIDER,
                    decks=2, skill_level=SL.MOSTLY_SKILL,
                    version='1.00fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = stack.GroundsForADivorceTalon


class LongTail(RelaxedSpider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 5 horz S _foundation_. Init deal 1 card. Build down in rank alone.
      Play seq by same suit. Full seq drop by same suit on _foundation_.

    _reserve_
      Pile 1 E. Init deal 1 card. Build any. Play top.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 4 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: CanfieldLayout.CanfieldLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    :cvar Stack _reserve_: stack.ReserveStack (max_cards=MAX)
    """
    __info__ = dict(id=570, name='Long Tail', game_type=GT.SPIDER, decks=1,
                    skill_level=SL.MOSTLY_SKILL, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = CanfieldLayout.CanfieldLayout
    _reserve_ = Wrap(stack.ReserveStack, max_cards=cs.MAX)

    def _create_game(self, **kw):
        kwdefault(kw, rows=5, playcards=16, reserves=1, resereves_text=True,
                  texts=True)
        return super(LongTail, self)._create_game(**kw)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 1 ea.
          - s[reserves] 2 ea up.

        .. \_start([]) -> None
        """
        self.s['talon'].dealRow()
        for i in range(2):
            self.s['talon'].dealRow(rows=self.s['reserves'])

    _quickplay_ = quickplay.LongTail


class ShortTail(LongTail):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 8 horz S _foundation_. Init deal 1 card. Build down in rank alone.
      Play seq by same suit. Full seq drop by same suit on _foundation_.

    _reserve_
      Pile 1 E. Init deal 1 card. Build any. Play top.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 4 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.SS_Foundation
    :cvar Stack _row_: spider.DropSS_RK_RowStack
    :cvar Stack _reserve_: stack.ReserveStack (max_cards=MAX)
    """
    __info__ = dict(id=571, name='Short Tail', game_type=(GT.SPIDER |
                    GT.ORIGINAL), decks=2,
                    skill_level=SL.MOSTLY_SKILL, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        kwdefault(kw, rows=8, playcards=24)
        return super(ShortTail, self)._create_game(**kw)


class FechtersGame(RelaxedSpider):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 12 horz S _foundation_. Init deal 4 alt open card. Build down in
      rank by alt color. Play seq. Full seq drop on _foundation_. Base KING.

    _talon_
      Pile 1 NW. Deal 1 card on _row_ with base KING seq.

    _foundation_
      Pile 8 horz N. Drop from _row_. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Hint _hint_: spider.Hint
    :cvar Stack _talon_: stack.FechtersTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: spider.AC_Foundation (base_rank=KING, mod=13)
    :cvar Stack _row_: spider.DropAC_RowStack (base_rank=KING)
    """
    __info__ = dict(id=685, name='Fechterʼs Game', game_type=GT.SPIDER,
                    decks=2, skill_level=SL.MOSTLY_SKILL,
                    version='1.00fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = stack.FechtersTalon
    _foundation_ = Wrap(spider.AC_Foundation, base_rank=cs.KING, mod=13)
    _row_ = Wrap(spider.DropAC_RowStack, base_rank=cs.KING)

    def _create_game(self, **kw):
        kw.setdefault('rows', 12)
        return super(ShortTail, self)._create_game(**kw)

    def _start(self, flips=[False, True] * 2, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 4 ea alt.

        .. \_start([flips=[False, True] * 2]) -> None
        """
        for flip in flips[:-1]:
            self.s['talon'].dealRow(flip=flip, frames=0)
        self.s['talon'].dealRow(flips[-1])


class RougeEtNoir(game.Game):
    """
    Drop seq on _foundation_ within a turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [8, 7, 6, 5, 4, 3, 2, 1, 1, 0]
      card. Build down in rank by alt color. Seq play. Drop full seq or finish
      card on _foundation_. Base KING.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 8 horz N. Drop from _row_: E card, W seq. Play none.

    seealso::
      <http://en.wikipedia.org/wiki/Rouge_et_Noir>
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundations_: stack.AC_Foundation (max_move=0),
      spider.AC_Foundation
    :cvar Stack _row_: spider.DropEitherAC_RowStack (base_rank=KING)
    """
    __info__ = dict(id=220, name='Rouge et Noir', game_type=GT.GYPSY,
                    decks=2, skill_level=SL.MOSTLY_SKILL,
                    version='4.60')
    __author__ = 'Markus Oberhumer'
    __credits__ = ['Charles Jewell']
    __version__ = 7.70

    _layout_ = layout.KlondikeLayout
    _talon_ = stack.DealRowTalon
    _foundations_ = (Wrap(stack.AC_Foundation, max_move=0),
                     spider.AC_Foundation,)
    _row_ = Wrap(spider.DropEitherAC_RowStack, base_rank=cs.KING)

    def _create_game(self, **kw):
        kwdefault(kw, rows=10, texts=True, playcards=23)
        return super(RougeEtNoir, self)._create_game(**kw)

    def _start(self, flip=False, reverse=True, **kw):
        """
        Deal initial cards for new game.
          - s[rows] LEN - 3..1, 1, 0 ea top. reversed.

        .. \_start([flip=False, reverse=True]) -> None
        """
        for i in range(3, len(self.s['rows'])):
            self.s['talon'].dealRow(rows=self.s['rows'][:-i], flip=flip,
                                    frames=0, reverse=reverse)
        self.s['talon'].dealRow(rows=self.s['rows'][:-1], reverse=reverse)


class Cicely(game.Game):
    """
    Finish cards on _foundation_ within a turn.

    _row_
      Pile 8 horz. Init deal 4 open cards. Build either in rank by same suit.
      Play top.

    _reserve_
      Pile 8 horz N _row_ Init deal 1 card. Build 1 card. Play top.

    _talon_
      Pile 1 NW. Deal _row_ 4 cards.

    _foundation_
      Pile 8 over 2 col E W. Build in rank by same suit. W up. E down. Play
      top.
    ------
    :cvar Stack _talon_: stack.DealRowTalon (num_cards=4)
    :cvar Stack _foundation_: stack.SS_Foundation,
      stack.SS_Foundation (base_rank=KING, dir=-1)
    :cvar Stack _row_: stack.UD_SS_RowStack
    :cvar Stack _reserve_: stack.ReserveStack
    :cvar Hint _hint_:  CautiousDefaultHint
    """
    __info__ = dict(id=341, name='Cicely', game_type=GT.SPIDER, decks=2,
                    skill_level=SL.BALANCED, version='0.90fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = layout.CicelyLayout
    _talon_ = Wrap(stack.DealRowTalon, num_cards=4)
    _foundations_ = (stack.SS_Foundation,
                     Wrap(stack.SS_Foundation, base_rank=cs.KING, dir=-1),)
    _row_ = stack.UD_SS_RowStack
    _reserve_ = stack.ReserveStack
    _hint_ = CautiousDefaultHint

    def _create_game(self, **kw):
        kwdefault(kw, rows=8, reserves=8, playcards=16)
        return super(Cicely, self)._create_game(**kw)

    def _start(self, rows=4, flip=True, **kw):
        """
        Deal initial cards for new game.
          - s[reserves] 1 ea
          - s[rows] 4 ea up.

        .. \_start([rows=4, flip=True]) -> None
        """
        self.s['talon'].dealRow(rows=self.s['reserves'], frames=0)
        for i in range(rows - 1):
            self.s['talon'].dealRow(frames=0, flip=flip)
        self.s['talon'].dealRow()


class Bebop(game.Game):
    """
    Finish cards on _foundation_ within a turn.

    _row_
      Pile 8 horz. Init deal 4 open card. Build down in rank alone. Play seq.
      Any top close card deal pile over others and reset when
      len cards same as len _row_ - 1 then deal _row_.

    _talon_
      Pile 1 NW.

    _foundation_
      Pile 8 N _row_. Build down in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.Talon
    :cvar Stack _foundation_: stack.SS_Foundation,
      stack.SS_Foundation (base_rank=KING, dir=-1)
    :cvar Stack _row_: stack.RK_RowStack
    """
    __info__ = dict(id=710, name='Bebop', game_type=(GT.TWO_DECK |
                    GT.ORIGINAL), decks=2, version='0.90fc',
                    skill_level=SL.MOSTLY_SKILL)
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = stack.Talon
    _foundation_ = stack.SS_Foundation
    _row_ = stack.RK_RowStack
    _layout_ = KlondikeLayout.KlondikeLayout

    def _create_game(self, **kw):
        kwdefault(kw, rows=8, texts=True, playcards=18)
        return super(Bebop, self)._create_game(**kw)

    def _start(self, rows=4, flip=False, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 4 ea top.

        .. \_start([rows=4, flip=False]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(frames=0, flip=flip)
        self.s['talon'].dealRow()

    @state.move_state('fill')
    def _auto_fill(self, stack):
        if stack in self.s['rows']:
            nrows = len(self.s['rows']) - 1
            if (len(stack.cards) == nrows and not stack.cards[-1].face_up):
                for row in (s for s in self.s['rows'] if s is not stack):
                    self.game.fill(stack, row, frames=4)
                ncards = min(nrows, len(self.s['talon'].cards))
                for i in range(ncards):
                    self.s['talon'].dealRow(rows=[stack], frames=4, flip=False)
                if self.s.talon.cards:
                    self.s['talon'].dealRow(rows=[stack])


class TheJollyRoger(game.Game):
    """
    Finish cards on _foundation_ within a turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.klondike.KlondikeLayout
        - row [13 horz S foundation, vert offset]
        - talon [1 NW, no offset]
        - foundation [10 over 2 N, no offset]
    _row_
      Pile 13 horz. Init deal 3 open cards. Build down in rank alone by 2, ACE
      pair. Play seq by same suit or ACE same color. Drop full seq or ACE set
      on _foundation.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 10 over 2 row N _row_. Drop from _row_. Play none.
    ------
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _foundation_: staack.SS_Foundation (dir=-2, base_rank=ANY,
      min_accept=6, max_cards=6, max_move=0), JollyRoger_Foundation (suit=ANY,
      dir=0, min_accept=4, max_accept=4, max_cards=4, max_move=0)
    :cvar Stack _row_: JollyRoger_RowStack (dir=-2)
    :cvar Hint _hint_: spider.Hint
    """
    __info__ = dict(id=711, name='Jolly Roger', game_type=(GT.SPIDER |
                    GT.ORIGINAL), decks=2, version='0.90fc',
                    skill_level=SL.MOSTLY_SKILL)
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = KlondikeLayout.KlondikeLayout
    _talon_ = stack.DealRowTalon
    _foundations_ = [Wrap(spider.SS_Foundation, dir=-2, base_rank=cs.ANY,
                          min_accept=6, max_cards=6, max_move=0),
                     Wrap(JollyRoger_Foundation, suit=cs.ANY, dir=0,
                          min_accept=4, max_accept=4, max_cards=4, max_move=0)]
    _row_ = Wrap(JollyRoger_RowStack, dir=-2)
    _hint_ = spider.Hint

    def _create_game(self, **kw):
        kwdefault(kw, rows=13, playcards=12)
        return super(Cicely, self)._create_game(**kw)

    def _start(self, rows=3, flip=True, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 3 ea up.

        .. \_start([rows=3, flip=True]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(flip=flip, frames=0)
        self.s['talon'].dealRow()

    _quickplay_ = quickplay.Spider


PROVIDES = [RelaxedSpider, Spider, BlackWidow, GroundsForADivorce,
            GrandmothersGame, Spiderette, BabySpiderette, WillOTheWisp,
            SimpleSimon, Rachel, Scorpion, Wasp, RougeEtNoir, Spider1Suit,
            Spider2Suits, ThreeBlindMice, MrsMop, Cicely, ScorpionHead,
            ScorpionTail, SpiderWeb, SimonJester, BigSpider,
            GroundsForADivorce3Decks, BigYork, York, BigSpider1Suit,
            BigSpider2Suits, Spider4Decks, GroundsForADivorce4Decks, Spidike,
            FredsSpider, Spider3x3, FredsSpider3Decks, DoubleScorpion,
            TripleScorpion, FarmersWife, HowTheyRun, LongTail, ShortTail,
            ChineseSpider, Incompatibility, ScorpionII, Tarantula,
            FechtersGame, Bebop, TheJollyRoger, OpenSpider, SimpleSimonII]